package com.quectel.cms.controller.propertybill;


import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.util.SessionHolder;
import com.quectel.constant.core.propertybill.PropertyChargeableConstant;
import com.quectel.constant.global.SystemConstants;
import com.quectel.util.aspect.log.annotation.Log;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.core.module.propertybill.dto.PropertyChargeableItemDto;
import com.quectel.core.module.propertybill.dto.PropertyChargeableListBindingDto;
import com.quectel.core.module.propertybill.dto.PropertyChargeableListDto;
import com.quectel.core.module.propertybill.dto.PropertyChargeableListItemBindingDto;
import com.quectel.core.module.propertybill.service.PropertyChargeableItemService;
import com.quectel.core.module.propertybill.service.PropertyChargeableListBindingService;
import com.quectel.core.module.propertybill.service.PropertyChargeableListItemBindingService;
import com.quectel.core.module.propertybill.service.PropertyChargeableListService;
import com.quectel.core.module.village.dto.VillageBuildingDto;
import com.quectel.core.module.village.service.VillageBuildingService;
import com.quectel.core.module.village.service.VillageRoomService;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author bob
 * @email bob.yu@quectel.com
 * @date 2023/03/31 14:36
 */
@RestController
@RequestMapping("propertyChargeableList")
@Tag(name = "PropertyChargeableListController", description = "物业收费标准配置相关api")
public class PropertyChargeableListController extends BaseController {

    @DubboReference
    private PropertyChargeableListService propertyChargeableListService;
    @DubboReference
    private PropertyChargeableListBindingService propertyChargeableListBindingService;
    @DubboReference
    private VillageBuildingService villageBuildingService;
    @DubboReference
    private VillageRoomService roomService;
    @DubboReference
    private PropertyChargeableItemService propertyChargeableItemService;
    @DubboReference
    private PropertyChargeableListItemBindingService propertyChargeableListItemBindingService;

    @GetMapping("queryAll")
    @Operation(summary = "查询小区下的收费标准")
    public Response<List<PropertyChargeableListDto>> queryAll(
            @Parameter(description = "小区Id") @RequestParam Long villageId
    ) {
        Request request = Request.configParamsNotPage(Request.parseParams(httpServletRequest));
        super.fillAuthorityData(request.getParams());
        request.put(LambdaUtil.getFieldName(PropertyChargeableListDto::getVillageId), villageId);
        request.put(LambdaUtil.getFieldName(PropertyChargeableListDto::getStatus), SystemConstants.YES);
        List<PropertyChargeableListDto> propertyChargeableListDtos = propertyChargeableListService.queryList(request.getParams());
        return Response.<List<PropertyChargeableListDto>>ok().wrap(propertyChargeableListDtos);
    }

    @GetMapping("queryVillageItem")
    @Operation(summary = "查询小区下的收费项目列表")
    public Response<List<PropertyChargeableItemDto>> queryVillageItem() {
        Map<String, Object> params = Request.parseParams(httpServletRequest);
        super.fillAuthorityData(params);
        List<PropertyChargeableItemDto> list = new ArrayList<>();
        if (StringUtils.isEmpty((CharSequence) params.get("villageId"))){
            return Response.<List<PropertyChargeableItemDto>>ok().wrap(list);
        }

        params.put(LambdaUtil.getFieldName(PropertyChargeableItemDto::getStatus), SystemConstants.YES);
        list = propertyChargeableItemService.queryList(params);
        return Response.<List<PropertyChargeableItemDto>>ok().wrap(list);
    }

    @GetMapping("queryBindSourceId")
    @Operation(summary = "查询已经绑定的楼栋id")
    public Response<Object> queryBindSourceId() {
        Request request = Request.configParamsNotPage(Request.parseParams(httpServletRequest));
        request.put(LambdaUtil.getFieldName(PropertyChargeableListBindingDto::getBindingType), PropertyChargeableConstant.SourceType.VILLAGE.getType());
        List<PropertyChargeableListBindingDto> propertyChargeableListBindingDtos = propertyChargeableListBindingService.queryList(request.getParams());
        return Response.ok().wrap(propertyChargeableListBindingDtos);
    }

    /**
     * 楼栋搜索
     */
    @GetMapping("queryAllBuilding")
    @Operation(summary = "查询权限下的小区楼栋列表")
    public Response<List<VillageBuildingDto>> queryAllBuilding() {

        Map<String, Object> params = Request.parseParams(httpServletRequest);
        super.fillAuthorityData(params);
        List<VillageBuildingDto> list = new ArrayList<>();
        if (StringUtils.isEmpty((CharSequence) params.get("villageId"))){
            return Response.<List<VillageBuildingDto>>ok().wrap(list);
        }
        list = villageBuildingService.queryList(params);
        return Response.<List<VillageBuildingDto>>ok().wrap(list);
    }

    @PostMapping("importExcel")
    @RequirePermissions(values = "propertyChargeableList:importExcel")
    @Operation(summary = "数据导入")
    public Response<Object> importExcel(
            MultipartHttpServletRequest request
    ) {
        final Long tenantId = SessionHolder.getSysUser().getTenantId();
        Date currentDate = new Date();
        int totalCount = 0;
        int successCount = 0;

//        List<MongoCarAccessRecordDto> carAccessRecordDtos = new ArrayList<>();
//        Iterator<String> fileNames = request.getFileNames();
//        while (fileNames.hasNext()) {
//            String next = fileNames.next();
//            List<MultipartFile> files = request.getFiles(next);
//            for (MultipartFile file : files) {
//                try {
//                    List<Map<Integer, String>> analysis = POIUtils.analysis(file.getInputStream(), 1, 0);
//                    totalCount += analysis.size();
//
//                    Map<String, List<Map<Integer, String>>> groupByVillageName = analysis.stream().collect(Collectors.groupingBy(o -> o.get(0)));
//                    for (String villageName : groupByVillageName.keySet()) {
//                        VillageDto villageDto = villageService.selectCacheByName(tenantId, villageName);
//                        if (villageDto == null) {
//                            continue;
//                        }
//
//                        List<Map<Integer, String>> maps = groupByVillageName.get(villageName);
//                        List<MongoCarAccessRecordDto> list = maps.stream().map(row -> {
//                            String deviceUniqueId = row.get(1);
//                            String license = row.get(2);
//                            String licenseColor = row.get(3);
//                            String carType = row.get(4);
//                            String snapImage = row.get(5);
//                            String accessTime = row.get(6);
//
//                            DeviceDto deviceDto = deviceService.selectCacheByUniqueId(deviceUniqueId, tenantId);
//                            if (deviceDto == null) {
//                                return null;
//                            }
//
//                            CarDto carDto = carService.selectOne(villageDto.getId(), license
//                                    , SysCodeUtils.easyToGetValue(SysCodeKeyConstants.LICENSE_COLOR, licenseColor, Byte.class));
//
//                            DeviceExtraAttrCls.AttrOfIntelligentParkingGate attrOfIntelligentEntranceGuard = DeviceExtraAttrCls
//                                    .parseExtStr(DeviceExtraAttrCls.AttrOfIntelligentParkingGate.class, deviceDto.getExtraAttr());
//
//                            MongoCarAccessRecordDto carAccessRecordDto = new MongoCarAccessRecordDto();
//                            carAccessRecordDto.setTenantId(tenantId);
//                            carAccessRecordDto.setVillageId(villageDto.getId());
//                            carAccessRecordDto.setDeviceCategoryId(deviceDto.getId());
//                            carAccessRecordDto.setDeviceTypeId(deviceDto.getDeviceTypeId());
//                            carAccessRecordDto.setCarId(carDto == null ? null : carDto.getId());
//                            carAccessRecordDto.setDeviceId(deviceDto.getId());
//                            carAccessRecordDto.setDeviceName(deviceDto.getName());
//                            carAccessRecordDto.setLicense(license);
//                            carAccessRecordDto.setLicenseColor(SysCodeUtils.easyToGetValue(SysCodeKeyConstants.LICENSE_COLOR, licenseColor, Byte.class));
//                            carAccessRecordDto.setCarType(SysCodeUtils.easyToGetValue(SysCodeKeyConstants.CAR_TYPE, carType, Byte.class));
//
//                            carAccessRecordDto.setOutOrIn(attrOfIntelligentEntranceGuard == null ? null : attrOfIntelligentEntranceGuard.getOutOrIn());
//
//                            carAccessRecordDto.setSnapImages(StringUtils.isNotBlank(snapImage) ? JacksonUtils.toJsonString(new String[]{snapImage}) : null);
//                            carAccessRecordDto.setAccessTime(StringUtils.isNotBlank(accessTime) ? DateUtils.parse(accessTime, DateUtils.FormatType.COMMON) : null);
//                            return carAccessRecordDto;
//                        }).filter(o -> o != null).collect(Collectors.toList());
//
//                        carAccessRecordDtos.addAll(list);
//                    }
//                } catch (Exception e) {
//                    logger.error("解析车辆出入数据出错",e);
//                }
//            }
//        }
//        carAccessRecordService.saveBatch(carAccessRecordDtos);
//        successCount = carAccessRecordDtos.size();
        return Response.error("导入数据完成 总数:" + totalCount + " 成功数:" + successCount);
    }


    @GetMapping("downloadExcel")
    @RequirePermissions(values = "propertyChargeableList:downloadExcel")
    @Operation(summary = "导出收费标准模板")
    @Log(express = "导出收费标准模板")
    public void exportExcel(@RequestParam Map<String, Object> params, HttpServletResponse hresp) {
        Request request = Request.configParamsNotPage(params);

        super.fillAuthorityData(params);

//        List<MongoCarAccessRecordDto> result = PageFetchKit.fetchAll(r -> carAccessRecordService.queryList(r), request.getParams());

//        String[] headers = new String[]{"所属小区", "设备名称", "车牌号", "车辆颜色", "车辆类型", "进出方式", "抓拍照片", "抓拍录像", "访问时间"};
//        List<String[]> dataList = new ArrayList<>();
//        for (MongoCarAccessRecordDto data : result) {
//            String[] item = new String[headers.length];
//            item[0] = data.getVillageDto().getName();
//            item[1] = data.getDeviceName();
//            item[2] = DesensitizedUtil.carLicense(data.getLicense());
//            item[3] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.LICENSE_COLOR, data.getLicenseColor() + "");
//            item[4] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.CAR_TYPE, data.getCarType() + "");
//            item[5] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.OUT_IN_TYPE, data.getOutOrIn() + "");
//            item[6] = data.getSnapImages();
//            item[7] = data.getSnapVideoes();
//            item[8] = data.getAccessTime() != null ? DateUtils.format(data.getAccessTime(), DateUtils.FormatType.COMMON) : null;
//            dataList.add(item);
//        }
//        POIUtils.exportExcel(hresp, "车辆出入记录", headers, dataList, "车辆出入记录");

    }


    /**
     * 物业收费项目作废操作
     */
    @PostMapping("cancel")
    @RequirePermissions(values = "propertyChargeableList:cancel")
    @Operation(summary = "物业收费项目作废操作")
    public Response<Object> cancel(@RequestBody Long[] ids) {
        for (Long id : ids) {
            PropertyChargeableListDto updately = new PropertyChargeableListDto();
            updately.setId(id);
            updately.setStatus(PropertyChargeableConstant.StatusEnum.CANCEL.getType());
            propertyChargeableListService.updateById(updately);
        }
        return Response.ok();
    }

    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @RequirePermissions(values = "propertyChargeableList:list")
    @Operation(summary = "分页获取物业收费标准配置列表")
    public Response<Page<PropertyChargeableListDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = propertyChargeableListService.queryTotal(request.getParams());

        List<PropertyChargeableListDto> list = null;
        if (total > 0) {
            list = propertyChargeableListService.queryList(request.getParams());
            Map<String, Object> sqlMap = new HashMap<>();
            for (PropertyChargeableListDto propertyChargeable : list) {
                if (propertyChargeable.getSourceType().equals(PropertyChargeableConstant.SourceType.VILLAGE.getType())) {
                    sqlMap.put(LambdaUtil.getFieldName(VillageBuildingDto::getVillageId), propertyChargeable.getVillageId());
                    int queryTotal = villageBuildingService.queryTotal(sqlMap);
                    propertyChargeable.setBindBuildingCount(queryTotal);
                }
                if (propertyChargeable.getSourceType().equals(PropertyChargeableConstant.SourceType.BUILDING.getType())) {
                    sqlMap.put(LambdaUtil.getFieldName(PropertyChargeableListBindingDto::getChargeableListId), propertyChargeable.getId());
                    propertyChargeable.setBindBuildingCount(propertyChargeableListBindingService.queryTotal(sqlMap));
                }
                sqlMap.clear();
                sqlMap.put(LambdaUtil.getFieldName(PropertyChargeableListItemBindingDto::getChargeableListId), propertyChargeable.getId());
                propertyChargeable.setBindItemCount(propertyChargeableListItemBindingService.queryTotal(sqlMap));
            }
        } else {
            list = new ArrayList<>();
        }

        Page<PropertyChargeableListDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<PropertyChargeableListDto>>ok().wrap(page);
    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "propertyChargeableList:edit")
    @Operation(summary = "在编辑时根据id查询物业收费标准配置详情")
    public Response<PropertyChargeableListDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (propertyChargeableListService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PropertyChargeableListDto propertyChargeableListDto = propertyChargeableListService.selectById(id);

        List<VillageBuildingDto> buildingList = new ArrayList<>();
        List<PropertyChargeableItemDto> itemList = new ArrayList<>();

        Map<String, Object> queryMap = new HashMap<>();

        if (PropertyChargeableConstant.SourceType.BUILDING.getType().equals(propertyChargeableListDto.getSourceType())) {
            queryMap.put(LambdaUtil.getFieldName(PropertyChargeableListBindingDto::getChargeableListId), id);
            List<PropertyChargeableListBindingDto> propertyChargeableListBindingDtos = propertyChargeableListBindingService.queryList(queryMap);
            for (PropertyChargeableListBindingDto listBinding : propertyChargeableListBindingDtos) {
                VillageBuildingDto villageBuildingDto = villageBuildingService.selectById(listBinding.getBindingId());
                buildingList.add(villageBuildingDto);
            }
        }

        queryMap.clear();
        queryMap.put(LambdaUtil.getFieldName(PropertyChargeableListItemBindingDto::getChargeableListId), id);
        List<PropertyChargeableListItemBindingDto> propertyChargeableListItemBindingDtos = propertyChargeableListItemBindingService.queryList(queryMap);
        for (PropertyChargeableListItemBindingDto listItemBinding : propertyChargeableListItemBindingDtos) {
            PropertyChargeableItemDto propertyChargeableItemDto = propertyChargeableItemService.selectById(listItemBinding.getChargeableItemId());
            itemList.add(propertyChargeableItemDto);
        }

        propertyChargeableListDto.setBuildingList(buildingList);
        propertyChargeableListDto.setItemList(itemList);

        return Response.<PropertyChargeableListDto>ok().wrap(propertyChargeableListDto);
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "propertyChargeableList:info")
    @Operation(summary = "根据id查询物业收费标准配置的详情")
    public Response<PropertyChargeableListDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (propertyChargeableListService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PropertyChargeableListDto propertyChargeableListDto = propertyChargeableListService.selectById(id);

        return Response.<PropertyChargeableListDto>ok().wrap(propertyChargeableListDto);
    }

    /**
     * 保存
     *
     * @param propertyChargeableListDto
     * @return
     */
    @PostMapping("save")
    @RequirePermissions(values = "propertyChargeableList:edit")
    @Operation(summary = "新增物业收费标准配置")
    public Response<Object> save(@RequestBody @Validated PropertyChargeableListDto propertyChargeableListDto) {

        //填充基础数据
        fillSaveCommonData(propertyChargeableListDto);

        // 选择楼栋 ，楼栋不可不传
        if (PropertyChargeableConstant.SourceType.BUILDING.getType().equals(propertyChargeableListDto.getSourceType())) {

            if (CollectionUtils.isEmpty(propertyChargeableListDto.getBuildingList())) {
                return Response.error("楼栋不可为空");
            }

        }

        if (PropertyChargeableConstant.SourceType.VILLAGE.getType().equals(propertyChargeableListDto.getSourceType())) {
            Map<String, Object> sqlMap = new HashMap<>();
            sqlMap.put(LambdaUtil.getFieldName(VillageBuildingDto::getVillageId), propertyChargeableListDto.getVillageId() + "");
            List<VillageBuildingDto> villageBuildingDtos = villageBuildingService.queryList(sqlMap);
            propertyChargeableListDto.setBuildingList(villageBuildingDtos);
        }

        if (CollectionUtils.isEmpty(propertyChargeableListDto.getItemList())) {
            return Response.error("项目不可为空");
        }

        propertyChargeableListService.saveOrUpdate(propertyChargeableListDto);

        return Response.ok();
    }


    /**
     * 修改
     *
     * @param propertyChargeableListDto
     * @return
     */
    @PostMapping("update")
    @RequirePermissions(values = "propertyChargeableList:edit")
    @Operation(summary = "根据id修改物业收费标准配置")
    public Response<Object> update(@RequestBody @Validated PropertyChargeableListDto propertyChargeableListDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(propertyChargeableListDto.getId()));
        if (propertyChargeableListService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //填充基础数据
        fillEditCommonData(propertyChargeableListDto);

        // 选择楼栋 ，楼栋不可不传
        if (PropertyChargeableConstant.SourceType.BUILDING.getType().equals(propertyChargeableListDto.getSourceType())) {

            if (CollectionUtils.isEmpty(propertyChargeableListDto.getBuildingList())) {
                return Response.error("楼栋不可为空");
            }

        }

        if (PropertyChargeableConstant.SourceType.VILLAGE.getType().equals(propertyChargeableListDto.getSourceType())) {
            Map<String, Object> sqlMap = new HashMap<>();
            sqlMap.put(LambdaUtil.getFieldName(VillageBuildingDto::getVillageId), propertyChargeableListDto.getVillageId() + "");
            List<VillageBuildingDto> villageBuildingDtos = villageBuildingService.queryList(sqlMap);
            propertyChargeableListDto.setBuildingList(villageBuildingDtos);
        }

        propertyChargeableListService.saveOrUpdate(propertyChargeableListDto);

        return Response.ok();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("delete")
    @RequirePermissions(values = "propertyChargeableList:delete")
    @Operation(summary = "根据多条记录id批量删除物业收费标准配置")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {

            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (propertyChargeableListService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }
        }

        propertyChargeableListService.deleteBatch(ids);

        return Response.ok();
    }
}
